<script setup lang="ts">
import { onMounted } from 'vue';
import { pipeline, env, type PipelineType, ImagePipelineInputs } from '@xenova/transformers';

onMounted(async () => {
    // 跳过本地模型检查
    env.allowLocalModels = false;
    // 引用我们将需要的元素
    const fanyiText = document.getElementById('fanyi-text') as HTMLInputElement;
    const fanyiJieguo = document.getElementById('fanyi-jieguo');
    const fanyiButton = document.getElementById('fanyi-button');
    const status = document.getElementById('status');
    const fileUpload = document.getElementById('file-upload');
    const imageContainer = document.getElementById('image-container');
    // 创建一个新的目标检测管道
    status.textContent = '1. 正在加载翻译模型...';
    const task1: PipelineType = 'translation';
    const detector1 = await pipeline(task1, 'Xenova/opus-mt-zh-en');
    status.textContent = '翻译模型准备好了...';

    status.textContent = '2. 正在加载图形模型...';
    const task2: PipelineType = 'object-detection';
    const detector2 = await pipeline(task2, 'Xenova/detr-resnet-50');
    status.textContent = '模型准备好了...';

    fanyiButton.onclick = async () => {
        const output = await detector1(fanyiText.value, {
            src_lang: 'zh', // Chinese
            tgt_lang: 'en', // English
        } as any);
        fanyiJieguo.textContent = JSON.stringify((output[0] as any).translation_text);
    };

    // 监听按钮并读取图像
    fileUpload.addEventListener('change', function (e) {
        const file = (e.target as HTMLInputElement).files[0];
        if (!file) return;
        const reader = new FileReader();
        // 在加载文件时设置回调
        reader.onload = function (e2) {
            imageContainer.innerHTML = '';
            const image = document.createElement('img');
            image.src = e2.target.result as string;
            imageContainer.appendChild(image);
            detect(image);
        };
        reader.readAsDataURL(file);
    });
    // 检测图像中的对象
    async function detect(img: HTMLImageElement) {
        status.textContent = '分析中...';
        const output = await detector2(img.src, {
            threshold: 0.5,
            percentage: true,
        });
        status.textContent = '';
        output.forEach(renderBox);
    }
    // 在图像上渲染边界框和标签
    function renderBox({ box, label }: any) {
        const { xmax, xmin, ymax, ymin } = box;
        // 为框生成随机颜色
        const color =
            '#' +
            Math.floor(Math.random() * 0xffffff)
                .toString(16)
                .padStart(6, '0');
        // 绘制方框
        const boxElement = document.createElement('div');
        boxElement.className = 'bounding-box';
        Object.assign(boxElement.style, {
            borderColor: color,
            left: 100 * xmin + '%',
            top: 100 * ymin + '%',
            width: 100 * (xmax - xmin) + '%',
            height: 100 * (ymax - ymin) + '%',
        });
        // 绘制标签
        const labelElement = document.createElement('span');
        labelElement.textContent = label;
        labelElement.className = 'bounding-box-label';
        labelElement.style.backgroundColor = color;
        boxElement.appendChild(labelElement);
        imageContainer.appendChild(boxElement);
    }
});
onMounted(async () => {});
</script>

<template>
    <main className="max-w-5xl bg-gray-100/[.80] m-auto my-8 p-8">
        <div className="text-center">
            <div>翻译：中==>英</div>
            <div>
                <input
                    id="fanyi-text"
                    className="px-2 py-1 outline-0 border border-cyan-500 hover:border-fuchsia-500"
                    type="text"
                    placeholder="请输入中文"
                />
                <button id="fanyi-button" className="bg-slate-500 hover:bg-slate-500/[.50] text-white px-2 py-1 ml-2">
                    翻译
                </button>
            </div>
            <div>
                翻译结果：
                <span id="fanyi-jieguo">xxx</span>
            </div>
        </div>
        <div class="container">
            <div>图片圈物体</div>
            <label class="custom-file-upload">
                <input id="file-upload" type="file" accept="image/*" />
                <img
                    class="upload-icon"
                    src="https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/upload-icon.png"
                />
                选择图片
            </label>
            <div id="image-container"></div>
            <p id="status"></p>
        </div>
    </main>
</template>

<style lang="scss" scoped>
.container {
    font-family: Arial, Helvetica, sans-serif;
    margin: 40px auto;
    width: max(50vw, 400px);
    display: flex;
    flex-direction: column;
    align-items: center;

    .custom-file-upload {
        display: flex;
        align-items: center;
        cursor: pointer;
        gap: 10px;
        border: 2px solid black;
        padding: 8px 16px;
        cursor: pointer;
        border-radius: 6px;
    }

    #file-upload {
        display: none;
    }

    .upload-icon {
        width: 30px;
    }

    #image-container {
        width: 100%;
        margin-top: 20px;
        position: relative;
    }

    #image-container > img {
        width: 100%;
    }
    .bounding-box {
        position: absolute;
        box-sizing: border-box;
    }

    .bounding-box-label {
        position: absolute;
        color: white;
        font-size: 12px;
    }
}
</style>
